package forum.dao.file;

import forum.dao.UserDAO;
import forum.entities.User;
import forum.exceptions.CreateExistingEntityException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import java.io.IOException;
import java.math.BigInteger;

public class FileUserDAO extends FileGenericDAO<User> implements UserDAO {

    public FileUserDAO() {
        super("src\\main\\resources\\users.xml","users","user");
    }


    @Override
    protected Element mapEntityToElement(Document document, Element element, User user) {

        Element userNode = document.createElement("user");
        element.appendChild(userNode);

        Element idNode = document.createElement("id");
        idNode.appendChild(document.createTextNode(user.getId().toString()));
        userNode.appendChild(idNode);

        Element emailNode = document.createElement("email");
        emailNode.appendChild(document.createTextNode(user.getEmail()));
        userNode.appendChild(emailNode);

        Element nickNameNode = document.createElement("nickName");
        nickNameNode.appendChild(document.createTextNode(user.getNickName()));
        userNode.appendChild(nickNameNode);

        Element passwordNode = document.createElement("password");
        passwordNode.appendChild(document.createTextNode(user.getPassword()));
        userNode.appendChild(passwordNode);

        return userNode;
    }

    @Override
    protected User mapElementToEntity(Document document, Element userNode) {
        User user = new User(new BigInteger(userNode.getElementsByTagName("id").item(0).getTextContent()));
        user.setEmail(userNode.getElementsByTagName("email").item(0).getTextContent());
        user.setNickName(userNode.getElementsByTagName("nickName").item(0).getTextContent());
        user.setPassword(userNode.getElementsByTagName("password").item(0).getTextContent());
        return user;
    }

    @Override
     public User findUserByEmail(String email) {
        User foundUser = null;
        try {
            Document document = getBuilder().parse(getDataFile());
            document.normalize();
            Element root = document.getDocumentElement();
            root.normalize();
            NodeList users = root.getElementsByTagName(getEntityTagName());
            for (int i = 0; i < users.getLength();i++) {
                Element tempEl = (Element)users.item(i);

                if (tempEl.getElementsByTagName("email").item(0).getTextContent().equals(email)) {
                    foundUser = mapElementToEntity(document, tempEl);
                }
            }
        } catch (SAXException e) {
            // TODO auto-generated try-catch block
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        } catch (IOException e) {
            // TODO auto-generated try-catch block
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }
        return foundUser;
    }

    @Override
    public User findUserByNickname(String nickname) {
        User foundUser = null;
        try {
            Document document = getBuilder().parse(getDataFile());
            document.normalize();
            Element root = document.getDocumentElement();
            root.normalize();
            NodeList users = root.getElementsByTagName(getEntityTagName());
            for (int i = 0; i < users.getLength();i++) {
                Element tempEl = (Element)users.item(i);

                if (tempEl.getElementsByTagName("nickName").item(0).getTextContent().equals(nickname)) {
                    foundUser = mapElementToEntity(document, tempEl);
                }
            }
        } catch (SAXException e) {
            // TODO auto-generated try-catch block
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        } catch (IOException e) {
            // TODO auto-generated try-catch block
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }
        return foundUser;
    }

    @Override
    protected User newEntity() {
        return new User(getNewKey());
    }

    @Override
    public void update(User entity) throws CreateExistingEntityException{
        if (findUserByEmail(entity.getEmail()) != null) {
            throw new CreateExistingEntityException("User with email "+ entity.getEmail() +" already exists");
        }
        if (findUserByNickname(entity.getNickName()) != null) {
            throw new CreateExistingEntityException("User with nickname"+ entity.getNickName() +" already exists");
        }
        super.update(entity);
    }


}
